package com.topisv.tms.service.stockChange;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.ProcessLog;
import com.topisv.tms.entity.stock.instorage.pre.InstorageBillPre;
import com.topisv.tms.entity.stockchange.StockChangeBill;
import com.topisv.tms.entity.stockchange.StockChangeBillItem;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.ProcessLogDao;
import com.topisv.tms.repository.stock.preInstorage.InstorageBillPreDao;
import com.topisv.tms.repository.stockChange.StockChangeBillDao;
import com.topisv.tms.repository.stockChange.StockChangeBillItemDao;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.utils.rule.TMSTransportRule;
import com.topisv.tms.utils.vo.StockChangeBillVo;

/**
 * 库存异动单_service
 * 
 * @author gh
 * 
 */
@Component
@Transactional(readOnly = true)
public class StockChangeBillService {

	@Autowired
	private StockChangeBillDao scbDao;
	@Autowired
	private StockChangeBillItemDao scbiDao;
	@Autowired
	private ProcessLogDao processLogDao;
	@Autowired
	private InstorageBillPreDao ibpDao;
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String save(StockChangeBillVo vo) throws Exception{
		
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		StockChangeBill scb = vo.getScb();
		
//		String orderCode = "";
		if("INSTORAGE".equals(scb.getOrderType())) {
			InstorageBillPre ibp = ibpDao.findByBillCode(scb.getOrderCode());
			if(ibp==null){
				return "bill_not_exist";
			}
//			orderCode = ibp.getCustomerOrderNo();
		}else {
			EdiOrder ediOrder = ediOrderDao.findByOrdeno(scb.getOrderCode());
			if(ediOrder==null){
				return "bill_not_exist";
			}
//			orderCode = ediOrder.getCustomerOrdeno();
		}
//		if(StringUtils.isEmpty(orderCode)){
//			return "bill_not_exist";
//		}
		
		scb.setBillCode(TMSTransportRule.generateByPreFix("SC"));
//		scb.setOrderCode(orderCode);
		scb.setCreateBy(user.getJobuuid());
		scb.setCreateTime(new Date());
		scb.setQuantity(0);
		scb.setStatus("unsend");
		
		
		List<StockChangeBillItem> scbiList = vo.getScbiList();
		Map<String,EdiGoodsSku> cacheSku = new HashMap<String,EdiGoodsSku>();
		for ( int i = 0 ; i < scbiList.size() ; i++) {
			StockChangeBillItem scbi = scbiList.get(i);
			
			EdiGoodsSku ediGoodsSku = getEdiGoodsSku(scb.getCustomerCode(), scbi.getSku(), cacheSku);
			if(ediGoodsSku==null){
				return "sku_not_exist_"+(i+1);
			}
			scbi.setId(null);
			scbi.setCustomerCode(scb.getCustomerCode());
			scbi.setWarehouseCode(scb.getWarehouseCode());
			scbi.setOrderType(scb.getOrderType());
			scbi.setOrderCode(scb.getOrderCode());
			scbi.setBillCode(scb.getBillCode());
			scb.setQuantity(scb.getQuantity()+(scbi.getQuantity()>0?scbi.getQuantity():-scbi.getQuantity()));
		}
		
		List<StockChangeBillItem> oldScbiList = scbiDao.findByBillCode(scb.getBillCode());
		scbiDao.delete(oldScbiList);
		
		scbDao.save(scb);
		scbiDao.save(scbiList);
		return "success";
	}
	
	public EdiGoodsSku getEdiGoodsSku(String customerCode,String sku,Map<String,EdiGoodsSku> cacheSku){
		EdiGoodsSku ediGoodsSku = null;
		if(cacheSku.get(customerCode+"_"+sku) != null){
			ediGoodsSku = cacheSku.get(customerCode+"_"+sku);
		}else {
			ediGoodsSku = ediGoodsSkuDao.findByCustomerCodeAndSku(customerCode ,sku);
		}
		return ediGoodsSku;
	}
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void sendStockChangeBill(Long id){
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		StockChangeBill scb = scbDao.findOne(id);
		scb.setStatus("send");
		scbDao.save(scb);
		
		ProcessLog pl = new ProcessLog("SEND_STOCK_CHANGE",user.getRealname()+"推送了异动单,单据号"+scb.getBillCode());
		processLogDao.save(pl);
	}
	
	public Page<StockChangeBill> findTable(final StockChangeBill config,int pageNumber,int pageSize){
		Sort sort = new Sort(Direction.DESC, "customerCode","warehouseCode","createTime");
		PageRequest pageRequest = new PageRequest(pageNumber-1, pageSize,sort);
		return scbDao.findAll(new Specification<StockChangeBill>() {
			@Override
			public Predicate toPredicate(Root<StockChangeBill> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Predicate pre = cb.conjunction();
				if (StringUtils.isNotBlank(config.getCustomerCode())) {
					pre.getExpressions().add(cb.equal(r.<String> get("customerCode"), config.getCustomerCode()));
				}
				if (StringUtils.isNotBlank(config.getWarehouseCode())) {
					pre.getExpressions().add(cb.equal(r.<String> get("warehouseCode"), config.getWarehouseCode()));
				}
				return pre;
			}

		},pageRequest);
	}
	public StockChangeBill queryById(Long id) {
		return scbDao.findOne(id);
	}
	public List<StockChangeBillItem> findItemByBillCode(String billCode) {
		return scbiDao.findByBillCode(billCode);
	}
	
	@Transactional(readOnly = false)
	public void delete(Long id){
		scbDao.delete(id);
	}
	
	
}